#include "Terminos.h"
#include <stdio.h>
#include <string.h>


Terminos::Terminos(string pArchvivoTerminos)
{
	cargarTerminos(pArchvivoTerminos);
	cantidadTerminos=terminos.size();
	CargarStopWords();
	currentDoc=0;
}

void Terminos::cargarFreqTerminos(string pArchvivoTerminos)
{
	string line, pTermino;
	
    ifstream myfile (pArchvivoTerminos.c_str());
 
    if (myfile.is_open())
    {
     while ( myfile.good() )
     {
      getline (myfile,line);
      pTermino = StringManager::splitByValue(line, &line, ' ');
      long frec = atol(line.c_str());
   	  //setTermino (pTermino);
      setFrecuencia(pTermino, 0, frec);
     }
    myfile.close();
    }
}

Terminos::Terminos()
{
	CargarStopWords();
}

Terminos::~Terminos()
{
	cantidadTerminos=0;

}

void Terminos::setCurrentDoc(unsigned int pNumDoc)
{
	currentDoc=pNumDoc;
}

void Terminos::cargarTerminos(string pArchvivoTerminos)
{
  string line;
 ifstream myfile (pArchvivoTerminos.c_str());
 
 if (myfile.is_open())
 {
   while ( myfile.good() )
   {
     getline (myfile,line);
     if (line != "")
    	 setTermino (line);
   }
   myfile.close();
 }
}

vector<string> & Terminos::split(string linea, vector<string> &elems) {

	/*string item="";

    for (unsigned int i=0; i<linea.length();i++)
    {
		if (tolower(linea[i])==delim)
		{
			if (item!= "")
				elems.push_back(item);
			item ="";
		}
		else
		{item +=tolower(linea[i]); }
    }
	if (item!= "")
		elems.push_back(item);*/

    string currentLine, aux;
    currentLine=linea;
	while(currentLine.length()>0)
	{
		string term = StringManager::toLower(StringManager::getTerm(currentLine,&aux));
		if ((term.length()>2) || (is_number(term)))
			elems.push_back(term);

		currentLine=aux;
	};

	return elems;
}


bool Terminos::is_number(string s)
{

	std::string::const_iterator it = s.begin();
    while (it != s.end() && isdigit(*it))
    	++it;
    return !s.empty() && it == s.end();
}

void Terminos::CargarStopWords()
{
	 string line;
	 ifstream myfile ("./configuracion/stopWords_en.unix.txt");

	 if (myfile.is_open())
	 {
	   while ( myfile.good() )
	   {
	     getline (myfile,line);
	     if (line != "")
      		 StopWords[line]='\0';

	   }
	   myfile.close();
	 }
}
/*
void Terminos::CargarCharsToRemuve()
{
	 string line;
	 ifstream myfile ("./configuracion/CharsToRemuve_en.txt");

	 if (myfile.is_open())
	 {
	   while ( myfile.good() )
	   {
	     getline (myfile,line);
	     if (line != "")
	    	 CharsToRemuve.push_back(line);
	   }
	   myfile.close();
	 }
}
*/
/*
string Terminos::RemoveCharts(string pTermino)
{
    bool endLoop1=false;
    bool endLoop2=false;
    char primerChar=pTermino[0];
    char ultimoChar=pTermino[pTermino.length()-1];
    char currentChar;
	for (unsigned int i=0; i<CharsToRemuve.size();i++)
    {
		currentChar=CharsToRemuve[i][0];
		if (primerChar==currentChar)
		{
			pTermino[0]='\0';
			endLoop1=true;
		}

		if (ultimoChar==currentChar)
		{
			pTermino[pTermino.length()-1]='\0';
			endLoop2=true;
		}

		if ((endLoop1) && (endLoop2))
			return pTermino;
    };

	return pTermino;
}

*/
void Terminos::ProsesarTerminos(string pLinea, string pModo)
{
	vector<string> newTerminos;
	newTerminos=split(pLinea,newTerminos);

	for(unsigned int j=0; j<newTerminos.size();j++)
	{
		if (pModo == "Crear")
		{
			//if (Biseccion(StopWords, newTerminos[j], 0,StopWords.size()-1)== -1 )
			if(StopWords.find(newTerminos[j]) == StopWords.end())
					setTermino(newTerminos[j]);
		}
		else
		{
			incrementFrecuencia(newTerminos[j],currentDoc);
		}

	};

}

void Terminos::ProsesarTerminosFull(string pLinea)
{
	vector<string> newTerminos;
	newTerminos=split(pLinea,newTerminos);

	for(unsigned int j=0; j<newTerminos.size();j++)
	{
		
			//if (Biseccion(StopWords, newTerminos[j], 0,StopWords.size()-1)== -1 ){
            if(StopWords.find(newTerminos[j]) == StopWords.end()){
                 //setTermino(newTerminos[j]);
			     //incrementFrecuencia(newTerminos[j],currentDoc);
			     setTerminoOrIncrement (newTerminos[j],currentDoc);
             }

	};

}
/*
 int Terminos::Biseccion(vector<string> pvector, string pTermino,int inicio,int largo)
 {
   int mitad = (largo+inicio)/2;

   if ((pvector.size()>0) && (inicio<=largo))
   {
	   if (pvector[mitad]==pTermino)
			return mitad;
	   else
		   if (pTermino>pvector[mitad])
			   return Biseccion(pvector,pTermino,mitad+1,largo);
		   else
			   return Biseccion(pvector,pTermino,inicio,mitad-1);
   };
   return -1;
 }
*/
 void Terminos::setTermino (string pTermino)
 {

	 if ((terminos.find(pTermino) == terminos.end()))
		{
		 termFrecByDoc frecuencia;
		 frecuencia.frec.push_back(0);
		 terminos[pTermino]=frecuencia;
		}

 }
 
 void Terminos::setTerminoOrIncrement (string pTermino,long pNumDoc)
 {

	 if ((terminos.find(pTermino) == terminos.end()))
		{
		 termFrecByDoc frecuencia;
		 frecuencia.frec.push_back(1);
		 terminos[pTermino]=frecuencia;
		}
	 else
	 {terminos[pTermino].frec[pNumDoc]++;};

 }


void Terminos::setFrecuencia(string pTermino,long pNumDoc, long pFrec)
{
	 if (terminos.find(pTermino) != terminos.end())
		{
		 terminos[pTermino].frec[pNumDoc] = pFrec;
		}
}

void Terminos::incrementFrecuencia(string pTermino,long pNumDoc)
{
	 if (terminos.find(pTermino) != terminos.end())
		{
		 terminos[pTermino].frec[pNumDoc]++;
		}
}

vector<double> Terminos::getFrecVector(long pNumDoc)
{
	map<string, termFrecByDoc>::iterator iterador = terminos.begin();
	vector<double> freciencias;
	while (iterador != terminos.end()) {
		freciencias.push_back(iterador->second.frec[pNumDoc]);
		iterador++;
	}
	return freciencias;
}

vector<string> Terminos::getTermVector()
{
	map<string, termFrecByDoc>::iterator iterador = terminos.begin();
	vector<string> terminosReturn;
	while (iterador != terminos.end()) {
		terminosReturn.push_back(iterador->first);
		iterador++;
	}
	return terminosReturn;
}

void Terminos::guardarEnArchivo(string pNombre)
{
	fstream frecTermByDocs;
	frecTermByDocs.open (pNombre.c_str(),ios::out);

	 map<string, termFrecByDoc>::iterator iterador = terminos.begin();
	string separator=" ";
	while (iterador != terminos.end()) {

			for(unsigned int j=0; j<iterador->second.frec.size();j++)
			{
				if (j==iterador->second.frec.size()-1)
					separator="";
				frecTermByDocs <<iterador->second.frec[j]<<separator;
				terminos[iterador->first].frec[j]=0;
			}

	    separator=" ";

		frecTermByDocs << "\n";
		iterador++;

	}
	frecTermByDocs.close();
}


void Terminos::guardarTerminos(string pNombre)
{
	fstream frecTermByDocs;
	frecTermByDocs.open (pNombre.c_str(),ios::out);
	map<string, termFrecByDoc>::iterator iterador = terminos.begin();

	while (iterador != terminos.end()) {

		frecTermByDocs << iterador->first <<"\n";
		iterador++;

	}
	frecTermByDocs.close();
}

void Terminos::guardarTerminosYFrecs(string pNombre)
{
     fstream frecTermByDocs;
	frecTermByDocs.open (pNombre.c_str(),ios::out);

	 map<string, termFrecByDoc>::iterator iterador = terminos.begin();
	string separator=" ";
	while (iterador != terminos.end()) {

			for(unsigned int j=0; j<iterador->second.frec.size();j++)
			{
                frecTermByDocs << iterador->first<<separator;
				if (j==iterador->second.frec.size()-1)
					separator="";
				frecTermByDocs <<iterador->second.frec[j]<<separator;
				terminos[iterador->first].frec[j]=0;
			}

	    separator=" ";

		frecTermByDocs << "\n";
		iterador++;

	}
	frecTermByDocs.close();
}
